﻿
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using System.Collections;
using Framework.Mathd;
namespace BridgeShips
{
    public class ShipsDictionary : MonoBehaviour
    {
        private static ShipsDictionary _instance;
        public static ShipsDictionary Instance
        {
            get
            {
                if (null == _instance)
                {
                    _instance = FindObjectOfType(typeof(ShipsDictionary)) as ShipsDictionary;
                }
                return _instance;
            }
        }

        /// <summary>
        /// 存放广告板的列表
        /// </summary>
        public List<GameObject> m_billBoardObject = new List<GameObject>();
        /// <summary>
        /// 舟船数据信息
        /// </summary>
        public Dictionary<uint, ShipProperty> shipDic = new Dictionary<uint, ShipProperty>();

        //类型选择 用于混合船（带式、分制式创建）
        public Dictionary<uint, ShipTypes> shipPrefabricateType = new Dictionary<uint, ShipTypes>();

        public List<uint> shipDicKey = new List<uint>();//字典的key值存储
                                                        //  public List<ShipProperty> shipDicBindedKey = new List<ShipProperty>();//行驶过程中绑定的船，合二为一的船
        public List<string> m_ShipsPosition = new List<string>();//存储ID和坐标的字符串
        private List<string> m_GetIDHead = new List<string>();//存放坐标头



        int m_GetIDIndex = 0;
        private static readonly Object m_shipsPositionLock = new Object();
        /// <summary>
        /// 初始化的数据
        /// </summary>
        public Dictionary<string, string> InitDic = new Dictionary<string, string>();
        /// <summary>
        /// 初始化坐标点
        /// </summary>
        private List<Vector2d> InitPosDic = new List<Vector2d>();
        private List<Vector3d> posList = new List<Vector3d>();//存放两个坐标用的
        //4桥节的ID
        private List<int> FourTypeIDList = new List<int>();
        //5桥节的ID
        private List<int> FiveTypeIDList = new List<int>();
        //8桥节
        private List<int> EightTypeIDList = new List<int>();
        //9桥节
        private List<int> NineTypeIDList = new List<int>();
        //10桥节
        private List<int> TenTypeIDList = new List<int>();
        private Vector3d uPosition;

        private int m_flag = 0;

        private TerrainMoveDate m_moveDate;
        private ShipsAllNumDate m_allNumDate;
        private ShipsIDDate m_shipsID;
        private ShipsPositionValuesDate m_shipsPositionValues;
        private CalibrationPositionDate m_calibrationPosition;

        public bool isCanUpdateDate = false;
        float m_timer = 0;//计时器

        public Sprite[] m_BillSprites;

        private void Start()
        {
            m_moveDate = new TerrainMoveDate();
            m_allNumDate = new ShipsAllNumDate();
            m_shipsID = new ShipsIDDate();
            m_shipsPositionValues = new ShipsPositionValuesDate();
            m_calibrationPosition = new CalibrationPositionDate();

        }

        public void AddShipPosition(string str)
        {
            //如果ID头列表中包含,修改
            if (m_GetIDHead.Contains(SpitReceivedMsgs.GetIDHead(str)))
            {
                m_GetIDIndex = m_GetIDHead.FindIndex(m_item => m_item.Equals(SpitReceivedMsgs.GetIDHead(str)));
                m_ShipsPosition[m_GetIDIndex] = str;
            }
            else
            {
                m_GetIDHead.Add(SpitReceivedMsgs.GetIDHead(str));
                m_ShipsPosition.Add(str);
            }
            /*
             * 原来的方法
            //lock (m_shipsPositionLock)
            //{
            //    m_ShipsPosition.Add(str);
            //}*/
        }
        /// <summary>
        /// 更新数据
        /// </summary>
        public void UpdateInitDate() {
            m_moveDate.GetDictionaryDate(InitDic["river"]);
            m_allNumDate.GetDictionaryDate(InitDic["AllNum"]);
            m_calibrationPosition.GetDictionaryDate(InitDic["Oposition"]);
            m_calibrationPosition.GetDictionaryDate(InitDic["Aposition"]);
            // m_calibrationPosition.GetDictionaryDate(InitDic["Bposition"]);

            if (InitDic.ContainsKey("FourID"))
            {
                m_shipsID.GetDictionaryDate(InitDic["FourID"]);
            }
            if (InitDic.ContainsKey("FiveID"))
            {
                m_shipsID.GetDictionaryDate(InitDic["FiveID"]);
            }
            if (InitDic.ContainsKey("EightID"))
            {
                m_shipsID.GetDictionaryDate(InitDic["EightID"]);
            }
            if (InitDic.ContainsKey("NineID"))
            {
                m_shipsID.GetDictionaryDate(InitDic["NineID"]);
            }
            if (InitDic.ContainsKey("TenID"))
            {
                m_shipsID.GetDictionaryDate(InitDic["TenID"]);
            }
        }
        private void Update()
        {
            if (isCanUpdateDate)
            {
                m_timer += Time.deltaTime;
                if (m_timer >= 1f)
                {
                    isCanUpdateDate = false;
                    UpdateInitDate();
                    m_timer = 0;
                }


            }
            if (m_ShipsPosition.Count > 0)
            {
                if (m_shipsPositionValues == null)
                    return;
                //Debug.LogError(m_ShipsPosition.Count);
                foreach (string item in m_ShipsPosition)
                {
                    m_shipsPositionValues.GetDictionaryDate(item);
                }
                /*
                 * 原来的接收方法
                //lock (m_shipsPositionLock)
                //{
                //    for (int i = 0; i < m_ShipsPosition.Count; i++)
                //    {

                //        m_shipsPositionValues.GetDictionaryDate(m_ShipsPosition[i]);
                //    }
                //    m_ShipsPosition.Clear();
                //}*/
            }
        }
        /// <summary>
        /// 向字典中添加数据
        /// </summary>
        public void AddShipDicValues(uint id, ShipProperty property)
        {
            //如果存在该id，则更新value值
            if (shipDic.ContainsKey(id))
            {
                shipDic[id] = property;
            }
            else
            {//不存在，则添加
                shipDic.Add(id, property);
            }
        }

        public void UpdateShipPrefabricateType(uint index, ShipTypes sType)
        {
            if (index < 0 && index > 16) return;
            uint id =  (index *2 - 1) * 100 + index + 1;
            if (shipPrefabricateType.ContainsKey(id))
            {
                shipPrefabricateType[id] = sType;
            }
            else
            {
                shipPrefabricateType.Add(id, sType);
            }
        }
        /// <summary>
        /// 移除字典中的值
        /// </summary>
        public void RemoveShipDicValue(uint id)
        {
            if (shipDic.ContainsKey(id))
            {
                shipDic.Remove(id);
            }
            else
            {
                return;
            }
        }
        /// <summary>
        /// 根据id来获取舟船的类型
        /// </summary>
        /// <param name="id"></param>
        public ShipProperty.ShipsType GetShipPropertyType(uint id)
        {
            //如果包含id,则返回类型，如果不包含id，返回None值
            if (shipDic.ContainsKey(id) )
            {
                return shipDic[id].Type;
            }
            else
            {
                return ShipProperty.ShipsType.None;
            }
        }

        public ShipTypes GetShipPrefabricateType(uint id)
        {
            //如果包含id,则返回类型，如果不包含id，返回None值
            if (shipPrefabricateType.ContainsKey(id))
            {
                return shipPrefabricateType[id];
            }
            else
            {
                return ShipTypes.LineType;
            }
        }
        /// <summary>
        /// 通过id来获取船的两个坐标
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<Vector3d> GetPositions(uint id)
        {
            posList.Clear();
            if (shipDic.ContainsKey(id))
            {
                posList.Add(shipDic[id].FirstPosition);
                posList.Add(shipDic[id].SecondPosition);
                return posList;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 通过周桥单元id来获取中心点坐标
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Vector3d GetPoisition(uint id)
        {
            if (shipDic.ContainsKey(id))
            {
                //如果ID 已经链接为 8/9/10桥接船 那么直接计算对应多桥接船体世界坐标
                Vector3 vPosition = GameEntry.Instance.CombinedDeformationManager.GetCombineShipPosition(id);
                if (vPosition.Equals(Vector3.zero) == false) {
                    uint combineID = (uint)vPosition.y;
                    shipDic[combineID].CenterPosition = new Vector3(vPosition.x, 7.0f, vPosition.z);
                }
                return shipDic[id].CenterPosition;
            }
            else
            {
                return new Vector3d(0.0, 7.0, 0.0);
            }
        }



        public Quaternion GetHeading(uint id)
        {
            if (shipDic.ContainsKey(id))
            {

                return shipDic[id].CurrentHeading;
            }
            else
            {
                return Quaternion.identity;
            }
        }
        /// <summary>
        /// 判断是否存在该ID值
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool IsExistID(uint id)
        {
            if (shipDic.ContainsKey(id))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 根据id来修改字典中的坐标值
        /// </summary>
        /// <param name="id"></param>
        /// <param name="pos1"></param>
        /// <param name="pos2"></param>
        public void ChangeShipDicValues(uint id, Vector3d pos, bool isFirst)
        {
            if (shipDic.ContainsKey(id))
            {

                if (isFirst)
                {
                    shipDic[id].FirstPosition = pos;
                }
                else
                {
                    shipDic[id].SecondPosition = pos;
                }
            }
            else
            {
                return;
            }
        }

        /// <summary>
        /// 根据id来修改字典中的坐标值
        /// </summary>
        /// <param name="id"></param>
        /// <param name="pos1"></param>
        /// <param name="pos2"></param>
        public void ChangeShipDicValues(uint id, Vector3d pos, ArrayList arrList)
        {

            if (shipDic.ContainsKey(id))
            {
                //shipDic[id].FirstPosition = arrList.get(0);
                //shipDic[id].SecondPosition = pos
            }
            else
            {
                return;
            }
        }

        public int Count()
        {
            return shipDic.Count;
        }
        /// <summary>
        /// 通过两个ID得到一个hash值,作为新的ID
        /// </summary>
        /// <param name="ID1"></param>
        /// <param name="ID2"></param>
        /// <returns></returns>
        /// #define PRIME_NUM 0x9e3779b9
        public uint HashCode(uint ID1, uint ID2)
        {
            // uint seed = ID1 *100 + ID2;
            //seed ^= ID2 * ID1  + (ID1 << 6) + (ID2 >> 2);
            return ID1 * 100 + ID2;
            // return (uint)(((uint)ID1 << 32) | (uint)ID2);
        }

        public uint HashCodeConvert(uint ID) {
            if (ID > 10000) {
                return (ID - 303) / 10201;
            }
            // uint seed = ID1 *100 + ID2;
            //seed ^= ID2 * ID1  + (ID1 << 6) + (ID2 >> 2);
            return ((ID - 1) / 101 + 1) / 2;
            // return (uint)(((uint)ID1 << 32) | (uint)ID2);
        }



        /// <summary>
        /// 获取原点坐标
        /// </summary>
        /// <returns></returns>
        public Vector2d GetOriginalPoint()
        {
            if (InitPosDic.Count < 1)
                return Vector2d.zero;
            return InitPosDic[0];
        }
        /// <summary>
        /// 获取另外一点坐标(非原点)
        /// </summary>
        /// <returns></returns>
        public Vector2d GetAPoint()
        {
            if (InitPosDic.Count <= 1)
                return Vector2d.zero;
            return InitPosDic[1];
        }
        /// <summary>
        /// 保存传入的校准坐标点
        /// </summary>
        /// <param name="HeadName"></param>
        /// <param name="value"></param>
        public void AddInitPosInDic(string HeadName, string value1, string value2)
        {
            if (InitPosDic.Count == 0)
            {
                InitPosDic.Add(Vector2d.zero);
                InitPosDic.Add(Vector2d.zero);
            }
            if (HeadName == "Oposition")
            {
                InitPosDic[0] = new Vector2d(double.Parse(value1), double.Parse(value2));
                m_flag = m_flag + 1;
            }
            else if (HeadName == "Aposition")
            {
                InitPosDic[1] = new Vector2d(double.Parse(value1), double.Parse(value2));
                m_flag = m_flag + 1;
            }

            if (m_flag == 2)
            {

                TransferOfAxes.Instance.InitBridgePosition();

            }

        }
        private IEnumerator MakeInit(float delayTime)
        {

            yield return new WaitForSeconds(delayTime);
            TerrainsMove.Instance.InitShip();
        }

        /// <summary>
        /// 存储传入的船的ID值
        /// </summary>
        /// <param name="headName"></param>
        /// <param name="ids"></param>
        public void SaveIDs(string headName, List<string> ids)
        {

            if (headName == "FourID")
            {
                for (int i = 0; i < ids.Count - 1; i++)
                {
                    if (!FourTypeIDList.Contains(int.Parse(ids[i + 1])))
                    {
                        FourTypeIDList.Add(int.Parse(ids[i + 1]));
                    }
                }

            }
            else if (headName == "FiveID")
            {
                for (int i = 0; i < ids.Count - 1; i++)
                {

                    if (!FiveTypeIDList.Contains(int.Parse(ids[i + 1])))
                    {
                        FiveTypeIDList.Add(int.Parse(ids[i + 1]));
                    }
                }
            }
            else if (headName == "EightID")
            {
                for (int i = 0; i < ids.Count - 1; i++)
                {

                    if (!EightTypeIDList.Contains(int.Parse(ids[i + 1])))
                    {
                        EightTypeIDList.Add(int.Parse(ids[i + 1]));
                    }
                }
            }
            else if (headName == "NineID")
            {
                for (int i = 0; i < ids.Count - 1; i++)
                {

                    if (!NineTypeIDList.Contains(int.Parse(ids[i + 1])))
                    {
                        NineTypeIDList.Add(int.Parse(ids[i + 1]));
                    }
                }
            }
            else if (headName == "TenID")
            {
                for (int i = 0; i < ids.Count - 1; i++)
                {

                    if (!TenTypeIDList.Contains(int.Parse(ids[i + 1])))
                    {
                        TenTypeIDList.Add(int.Parse(ids[i + 1]));
                    }
                }
            }
        }
        ///// <summary>
        ///// 根据船的id来获取类型值
        ///// </summary>
        ///// <param name="ID"></param>
        ///// <returns></returns>
        //public int GetTypeForID(int ID) {
        //    if (FourTypeIDList.Contains(ID)) {
        //        return 4;
        //    }
        //    else if (FiveTypeIDList.Contains( ID )) {
        //        return 5;
        //    }
        //    else if (EightTypeIDList.Contains( ID )) {
        //        return 8;
        //    }
        //    else if (NineTypeIDList.Contains( ID )) {
        //        return 9;
        //    }
        //    else if (TenTypeIDList.Contains( ID )) {
        //        return 10;
        //    }
        //    else {
        //        return 0;
        //    }
        //}
        /// <summary>
        /// 拿到第n个key
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public uint GetDicKey(int num)
        {
            foreach (var item in shipDic.Keys)
            {
                if (!shipDicKey.Contains(item))
                {
                    if (shipDic[item].Valid)
                    {
                        shipDicKey.Add(item);
                    }
                }
            }
            return shipDicKey[num];
        }
        /// <summary>
        /// 坐标转换,将经纬度的2D坐标转换成Unity中使用的世界坐标
        /// </summary>
        /// <param name="value">经纬度</param>
        /// <returns></returns>
        public Vector3d ConvertToUnityPosition(string x, string y)
        {
            //转换过程
            uPosition = TransferOfAxes.Instance.ChangeLatLngSpaceToUnitySceneSpace(x, y);
            return uPosition;
        }

        //船中途合并，变化动态改变 船只物体搜寻列表
        public void UpdateShipListState()
        {
            foreach (var key in shipDic.Keys)
            {
                var Value =shipDic[key];
                ShipProperty.ShipsType eType = GameEntry.Instance.CombinedDeformationManager.GetCompineDefType(Value.Id1, Value.Id2);
                uint newID = ShipsDictionary.Instance.HashCode(Value.Id1, Value.Id2);
                if (Value.Valid)
                {
                    shipDicKey.Add(key);
                }
            }

        }
    }
}